package example.demo.threadpool;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Exchanger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

public class CostumerThreadPool {
    BlockingQueue<Runnable> runnables;
    int coreSize;
    int maxSize;
    List<Worker> nothingWorkers = new LinkedList<>();
    List<Worker> busyWorks = new LinkedList<>();
    private int size;
    Lock lock = new ReentrantLock();

    public CostumerThreadPool(int queueMaxSize, int coreSize, int maxSize) {
        this.runnables = new ArrayBlockingQueue<>(queueMaxSize);
        this.coreSize = coreSize;
        this.maxSize = maxSize;
    }

    private final class Worker implements Runnable {
        Runnable runnable;
        Exchanger<Object> taskResult;

        public Worker(Runnable runnable) {
            this.runnable = runnable;
        }

        @Override
        public void run() {
            while (true) {
                if (null == runnable) {
                    LockSupport.park();
                }
                try {
                    runnable.run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                busyWorks.remove(this);
                nothingWorkers.add(this);
                runnable = null;
            }
        }
    }

    public Exchanger<Object> submitTask(Runnable runnable) {
        lock.lock();
        try {
            if (size < coreSize) {
                Worker worker = new Worker(runnable);
                new Thread(worker).start();
                busyWorks.add(worker);
                size++;
            }
        } finally {
            lock.unlock();
        }
        Exchanger<Object> result = new Exchanger<>();
        return result;
    }

    public void executeTask(Runnable runnable) {
        Exchanger<Object> result = new Exchanger<>();
    }
}
